package com.lhkj.ct.base.utils.chart;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtils;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.StandardChartTheme;
import org.jfree.chart.annotations.XYBoxAnnotation;
import org.jfree.chart.annotations.XYLineAnnotation;
import org.jfree.chart.annotations.XYTextAnnotation;
import org.jfree.chart.axis.*;
import org.jfree.chart.labels.*;
import org.jfree.chart.plot.*;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.chart.renderer.category.StackedBarRenderer;
import org.jfree.chart.renderer.category.StandardBarPainter;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.chart.title.LegendTitle;
import org.jfree.chart.title.TextTitle;
import org.jfree.chart.ui.*;
import org.jfree.chart.util.ShapeUtils;
import org.jfree.chart.util.UnitType;
import org.jfree.data.Range;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DatasetUtils;
import org.jfree.data.general.DefaultPieDataset;
import org.jfree.data.xy.XYDataset;

import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.Consumer;

/**
  * <p>
  *     描述：绘制图表
  * </p>
  */
public class JFreeChartUtil {

    static {
        // TODO 解决中文乱码问题
        //创建主题样式
        StandardChartTheme standardChartTheme = new StandardChartTheme("CN");
        //设置标题字体
        standardChartTheme.setExtraLargeFont(new Font("宋体", Font.BOLD, 20));
        //设置图例的字体
        standardChartTheme.setRegularFont(new Font("宋体", Font.PLAIN, 15));
        //设置轴向的字体
        standardChartTheme.setLargeFont(new Font("宋体", Font.PLAIN, 15));
        // 图表背景色
        standardChartTheme.setChartBackgroundPaint(Color.WHITE);
        // 绘制区域背景色
        standardChartTheme.setPlotBackgroundPaint(Color.white);
        // 绘制区域外边框
        standardChartTheme.setPlotOutlinePaint(Color.WHITE);
        // 设置X,Y轴相对（原点）距离
        standardChartTheme.setAxisOffset(RectangleInsets.ZERO_INSETS);
        // X坐标轴垂直网格颜色
        standardChartTheme.setDomainGridlinePaint(new Color(230, 230, 230));
        // Y坐标轴水平网格颜色
        standardChartTheme.setRangeGridlinePaint(new Color(230, 230, 230));

//        standardChartTheme.setSmallFont(new Font("宋体", Font.PLAIN, 15));
//
//        standardChartTheme.setTitlePaint(new Color(51, 51, 51));//Paint 可以理解为绘制颜色；标题字体颜色
//
//        standardChartTheme.setSubtitlePaint(new Color(85, 85, 85));//副标题字体颜色
//
//        standardChartTheme.setLegendBackgroundPaint(Color.WHITE);// 设置标注背景色
//
//        standardChartTheme.setLegendItemPaint(Color.BLACK);//设置字体颜色
//
//        // 绘制颜色绘制颜色.轮廓供应商
//
//        // paintSequence,outlinePaintSequence,strokeSequence,outlineStrokeSequence,shapeSequence
//
//        Paint[] OUTLINE_PAINT_SEQUENCE = new Paint[] { Color.WHITE };//外边框线条颜色
//
//        //绘制器颜色源-所有线条 饼图 默认颜色都是来自DefaultDrawingSupplier
//
//        DefaultDrawingSupplier drawingSupplier = new DefaultDrawingSupplier(CHART_COLORS, CHART_COLORS, OUTLINE_PAINT_SEQUENCE,
//
//                DefaultDrawingSupplier.DEFAULT_STROKE_SEQUENCE, DefaultDrawingSupplier.DEFAULT_OUTLINE_STROKE_SEQUENCE,
//
//                DefaultDrawingSupplier.DEFAULT_SHAPE_SEQUENCE);
//
//        standardChartTheme.setDrawingSupplier(drawingSupplier);//设置绘制颜色、线条、外边框供应商
//
//        standardChartTheme.setLabelLinkPaint(new Color(8, 55, 114));// 链接标签颜色
//
//        standardChartTheme.setLabelLinkStyle(PieLabelLinkStyle.CUBIC_CURVE);
//
//        standardChartTheme.setBaselinePaint(Color.WHITE);
//
//        standardChartTheme.setCrosshairPaint(Color.BLUE);// 不确定含义
//
//        standardChartTheme.setAxisLabelPaint(new Color(51, 51, 51));// 坐标轴标题文字颜色
//
//        standardChartTheme.setTickLabelPaint(new Color(67, 67, 72));// 刻度数字颜色
//
//        standardChartTheme.setBarPainter(new StandardBarPainter());// 设置柱状图渲染问哦基本渲染，不采用渐变
//
//        standardChartTheme.setXYBarPainter(new StandardXYBarPainter());// XYBar 渲染，值使用颜色渲染，不采用渐变
//
//        standardChartTheme.setItemLabelPaint(Color.black);
//
//        standardChartTheme.setThermometerPaint(Color.white);// 温度计
        //应用主题样式
        ChartFactory.setChartTheme(standardChartTheme);
    }

    /**
     * 绘制横向柱状图
     *
     * @param config     图表配置参数
     * @param dataset    图表内容数据
     */
    public static BufferedImage drawHorizontalBarChart(JFreeChartConfig config, DefaultCategoryDataset dataset) {

        /**
         * 标题,目录轴的显示标签,数值的显示标签,数据,图标方向  水平/垂直,是否显示图例，是否生成工具，是否生成URL链接
         */
        JFreeChart barChart = ChartFactory.createBarChart(config.getTitle(),
                config.getCategoryAxisLabel(), config.getValueAxisLabel(), dataset,
                PlotOrientation.HORIZONTAL, false, false, false);
        //获得图表区域对象
        CategoryPlot plot = (CategoryPlot) barChart.getPlot();
        // 设置范围轴的位置
        plot.setRangeAxisLocation(AxisLocation.BOTTOM_OR_LEFT);
        // 设置启用或禁用沿范围轴平移绘图的标志。
        plot.setRangePannable(true);
        //数据轴网格是否可见
        plot.setRangeGridlinesVisible(true);
        //设置数据轴网格线宽度，不设置为虚线
        plot.setRangeGridlineStroke(new BasicStroke(1F));

        // TODO 柱子设置
        BarRenderer renderer = (BarRenderer) plot.getRenderer();
        // 组内柱子间隔为组宽的10%
//        renderer.setItemMargin(0.1);
        // 设置柱子为平面图不是立体的
        renderer.setBarPainter(new StandardBarPainter());
        plot.getRenderer().setSeriesStroke(0, new BasicStroke(2.0F, 1, 1, 1.0F, new float[]{10.0F, 6.0F}, 0.0F));
        // 柱子颜色
        GradientPaint gp0 = new GradientPaint(0.0F, 0.0F, new Color(124, 181, 236), 0.0F, 0.0F, new Color(124, 181, 236));
        // 组内第一组柱子颜色
        renderer.setSeriesPaint(0, gp0);
        // 设置柱子值的文字和柱子之间距离
        renderer.setItemLabelAnchorOffset(1.0D);
        // 是否显示柱子值
        renderer.setDefaultItemLabelsVisible(true);
        // 柱子值显示竖直
//        renderer.setDefaultItemLabelGenerator(new StandardCategoryItemLabelGenerator());

        // 图片中显示百分比:自定义方式，{0} 表示选项， {1} 表示数值， {2} 表示所占比例 ,小数点后两位
        renderer.setDefaultItemLabelGenerator(new StandardCategoryItemLabelGenerator("{2}", new DecimalFormat("0.0")));
        // 设置柱子宽度
        renderer.setMaximumBarWidth(0.03);
        // TODO 设置图表的分类轴
        CategoryAxis categoryAxis = plot.getDomainAxis();
        // 柱状之间的距离20%
        categoryAxis.setCategoryMargin(0.2D);
        //设置柱状距离图片右端距离此时为百分之20
//        categoryAxis.setUpperMargin(0.5D);
//        //设置柱状距离图片左端距离此时为20%
//        categoryAxis.setLowerMargin(0.3D);

        // 设置xy轴线颜色
        categoryAxis.setAxisLinePaint(new Color(204, 214, 235));

//        // 设置刻度在柱状图内长度
//        categoryAxis.setTickMarkInsideLength(555);
//        // 设置刻度在柱状图外长度
        categoryAxis.setTickMarkOutsideLength(5);
        // TODO 设置图表的数据轴的标签 x
//        ValueAxis valueAxis = plot.getRangeAxis();
//        valueAxis.setLabelPaint(new Color(219, 18, 31));

        // TODO 设置数字轴 y
        NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
        // 设置数据轴刻度单位
//        rangeAxis.setTickUnit(new NumberTickUnit(5D));
        // 自动创建数据轴刻度单位
        rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
        rangeAxis.setUpperMargin(0.1D);
        // 是否显示刻度
        rangeAxis.setTickMarksVisible(false);
        rangeAxis.setAxisLinePaint(new Color(204, 214, 235));
        // 设置图表背景图颜色
        if (null != config.getBackgroundColor()) {
            barChart.getPlot().setBackgroundPaint(config.getBackgroundColor());
        }
        // 设置图表边框的颜色
        if (null != config.getOutlineColor()) {
            barChart.getPlot().setOutlinePaint(config.getOutlineColor());
        }
        // 设置图表背景图
        if (null != config.getBackgroundImage()) {
            barChart.getPlot().setBackgroundImage(config.getBackgroundImage());
        }
        return barChart.createBufferedImage(config.getWidth(), config.getHeight(), BufferedImage.TYPE_INT_RGB, null);
    }

    /**
     * 绘制纵向百分比柱状图
     *
     * @param config     图表配置参数
     * @param dataset    图表内容数据
     */
    public static BufferedImage drawPercentBarChart(JFreeChartConfig config, DefaultCategoryDataset dataset) {
        /**
         * 标题,目录轴的显示标签,数值的显示标签,数据,图标方向  水平/垂直,是否显示图例，是否生成工具，是否生成URL链接
         */
        JFreeChart barChart = ChartFactory.createBarChart(config.getTitle(),
                config.getCategoryAxisLabel(), config.getValueAxisLabel(), dataset,
                PlotOrientation.VERTICAL, false, false, false);

        //获得图表区域对象
        CategoryPlot plot = (CategoryPlot) barChart.getPlot();
        // 设置启用或禁用沿范围轴平移绘图的标志。
        plot.setRangePannable(true);
        //数据轴网格是否可见
        plot.setRangeGridlinesVisible(true);
        //设置数据轴网格线宽度，不设置为虚线
        plot.setRangeGridlineStroke(new BasicStroke(1F));
        // TODO 柱子设置
        BarRenderer renderer = (BarRenderer) plot.getRenderer();
        // 设置柱子为平面图不是立体的
        renderer.setBarPainter(new StandardBarPainter());
        // 柱子颜色
        GradientPaint gp0 = new GradientPaint(0.0F, 0.0F, new Color(0, 0, 0), 0.0F, 0.0F, new Color(0, 0, 0));
        for (int i = 0; i < dataset.getRowCount(); i++) {
            renderer.setSeriesPaint(i, gp0);
        }

        // 设置柱子值的文字和柱子之间距离
        renderer.setItemLabelAnchorOffset(1.0D);
        renderer.setDefaultItemLabelFont(new Font("宋体", 0, 10));
        // 是否显示柱子值
        renderer.setDefaultItemLabelsVisible(true);
        // 柱子值显示竖直
//        renderer.setDefaultItemLabelGenerator(new StandardCategoryItemLabelGenerator());
        // 图片中显示百分比:自定义方式，{0} 表示选项SeriesKeyName， {1} 为x值， {2} 为Y值
        renderer.setDefaultItemLabelGenerator(new StandardCategoryItemLabelGenerator("({0}){2}", new DecimalFormat("0.00%")));
        // 设置柱子宽度
        renderer.setMaximumBarWidth(0.05);
        // 设置柱之间距离
        renderer.setItemMargin(0.1);

        // TODO 设置图表的分类轴 x
        CategoryAxis categoryAxis = plot.getDomainAxis();
        // 柱状之间的距离20%
        categoryAxis.setCategoryMargin(0.01D);
        // 分类轴颜色
        categoryAxis.setAxisLinePaint(new Color(204, 214, 235));
//        // 设置刻度在柱状图外长度
        categoryAxis.setTickMarkOutsideLength(5);

        // TODO 设置图表的数据轴的标签 y
//        ValueAxis valueAxis = plot.getRangeAxis();
//        valueAxis.setLabelPaint(new Color(219, 18, 31));

        // TODO 设置数字轴 y
        NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
        // 设置数据轴刻度单位
//        rangeAxis.setTickUnit(new NumberTickUnit(2D));
        // 设置数据轴为百分比
        NumberFormat nf = new DecimalFormat("0%");
        nf.setMaximumFractionDigits(1);
        nf.format(0.2D);
        rangeAxis.setNumberFormatOverride(nf);//y轴节点格式
        // 设置数据轴区间
        rangeAxis.setRange(new Range(0, 1));
        // 自动创建数据轴刻度单位
        rangeAxis.setUpperMargin(0.1D);
        // 隐藏y轴
        rangeAxis.setAxisLineVisible(false);
        // 是否显示刻度
        rangeAxis.setTickMarksVisible(false);

        // 设置图表背景图颜色
        barChart.getPlot().setBackgroundPaint(config.getBackgroundColor());
        // 隐藏边框
        plot.setOutlineVisible(false);
        return barChart.createBufferedImage(config.getWidth(), config.getHeight(), BufferedImage.TYPE_INT_RGB, null);
    }


    /**
     * 绘制纵向柱状图
     *
     * @param config     图表配置参数
     * @param dataset    图表内容数据
     */
    public static BufferedImage drawVerticalBarChart(JFreeChartConfig config, DefaultCategoryDataset dataset){
        JFreeChart barChart = ChartFactory.createBarChart(config.getTitle(),
                config.getCategoryAxisLabel(), config.getValueAxisLabel(), dataset,
                PlotOrientation.VERTICAL, false, false, false);
        CategoryPlot plot = (CategoryPlot)barChart.getPlot();
        //数据轴网格是否可见
        plot.setRangeGridlinesVisible(true);
        //设置数据轴网格线宽度，不设置为虚线
        plot.setRangeGridlineStroke(new BasicStroke(1F));
        // 设置分类加个
        plot.getDomainAxis().setCategoryMargin(0.2D);

        NumberAxis rangeAxis = (NumberAxis)plot.getRangeAxis();
        rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
        rangeAxis.setAxisLineVisible(false);

        // TODO 柱子设置
        BarRenderer renderer = (BarRenderer)plot.getRenderer();

        // 设置柱子为平面图不是立体的
        renderer.setBarPainter(new StandardBarPainter());
        // 柱子颜色
        GradientPaint gp0 = new GradientPaint(0.0F, 0.0F, new Color(81, 114, 202), 0.0F, 0.0F, new Color(81, 114, 202));
        renderer.setSeriesPaint(0, gp0);

        // 设置柱子最大宽度
        renderer.setMaximumBarWidth(0.1);
        // 设置柱之间距离
        renderer.setItemMargin(0.1D);
        renderer.setLegendItemToolTipGenerator(new StandardCategorySeriesLabelGenerator("Tooltip: {0}"));

        // TODO 设置图表的分类轴
        CategoryAxis categoryAxis = plot.getDomainAxis();
        // 设置xy轴线颜色
        categoryAxis.setAxisLinePaint(new Color(204, 214, 235));

        // 设置图表背景图颜色
        barChart.getPlot().setBackgroundPaint(config.getBackgroundColor());
        // 隐藏边框
        plot.setOutlineVisible(false);
        return barChart.createBufferedImage(config.getWidth(), config.getHeight(), BufferedImage.TYPE_INT_RGB, null);
    }

    /**
     * 绘制纵向折线图，并生成图片
     *
     * @param config     图表配置参数
     * @param dataset    图表内容数据
     */
    public static BufferedImage drawVerticalLineChart(JFreeChartConfig config, DefaultCategoryDataset dataset) {
        return drawLineChart(config, dataset, null);
    }

    /**
     * 绘制横向折线图，并生成图片
     *
     * @param config     图表配置参数
     * @param dataset    图表内容数据
     */
    public static BufferedImage drawHorizontalLineChart(JFreeChartConfig config, DefaultCategoryDataset dataset) {
        return drawLineChart(config, dataset, e-> {
            ((CategoryPlot) e.getPlot()).setOrientation(PlotOrientation.HORIZONTAL);
        });
    }

    /**
     * 绘制横向折线图(带基线)，并生成图片
     *
     * @param config     图表配置参数
     * @param dataset    图表内容数据
     */
    public static BufferedImage drawVerticalLineChartWithMaker(JFreeChartConfig config, DefaultCategoryDataset dataset, double ... makerValues) {
        return drawLineChart(config, dataset, e-> {
            CategoryPlot plot = (CategoryPlot) e.getPlot();
            plot.setOrientation(PlotOrientation.VERTICAL);
            if (makerValues != null) {
                for (double makerValue : makerValues) {
                    ValueMarker valueMarker = new ValueMarker(makerValue, Color.RED, new BasicStroke(1F));
                    plot.addRangeMarker(valueMarker);
                }
            }
        });
    }

    /**
     * 绘制折线图，并生成图片
     *
     * @param config     图表配置参数
     * @param dataset    图表内容数据
     */
    public static BufferedImage drawLineChart(JFreeChartConfig config, DefaultCategoryDataset dataset, Consumer<JFreeChart> consumer) {
        JFreeChart lineChart = ChartFactory.createLineChart(config.getTitle(),
                config.getCategoryAxisLabel(), config.getValueAxisLabel(), dataset,
                PlotOrientation.VERTICAL, false, true, false);
        CategoryPlot plot = (CategoryPlot) lineChart.getPlot();
        //数据轴网格是否可见
        plot.setRangeGridlinesVisible(true);
        //设置数据轴网格线宽度，不设置为虚线
        plot.setRangeGridlineStroke(new BasicStroke(1F));

        // TODO 设置图表的分类轴
        CategoryAxis categoryAxis = plot.getDomainAxis();
        // 柱状之间的距离20%
//        categoryAxis.setCategoryMargin(0.15D);
        // 设置xy轴线颜色
        categoryAxis.setAxisLinePaint(new Color(204, 214, 235));
        categoryAxis.setCategoryLabelPositions(CategoryLabelPositions.createUpRotationLabelPositions(0.75));

        // 设置折线
        LineAndShapeRenderer renderer = (LineAndShapeRenderer)plot.getRenderer();
        // 显示折线数值
        renderer.setDefaultItemLabelsVisible(true);
        renderer.setDefaultItemLabelGenerator(new StandardCategoryItemLabelGenerator());
        // 设置显示节点
        renderer.setDefaultShapesVisible(true);
        renderer.setDrawOutlines(true);
        // 设置节点使用填充的颜色
        renderer.setUseFillPaint(true);
        // 设置节点填充颜色
        renderer.setDefaultFillPaint(new Color(124, 181, 236));
        // 设置折线粗细
        renderer.setSeriesStroke(0, new BasicStroke(2.0F));
        // 设置节点大小
        renderer.setSeriesOutlineStroke(0, new BasicStroke(2.0F));
        // 设置节点大小
        renderer.setSeriesShape(0, new Ellipse2D.Double(-2.5D, -2.5D, 5.0D, 5.0D));

        // 设置数据轴顶端距离10%
        NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
        rangeAxis.setUpperMargin(0.15D);

        TickUnits units = new TickUnits();
        units.add(new NumberTickUnit(100.0D, NumberFormat.getNumberInstance()));
        units.add(new NumberTickUnit(50.0D, NumberFormat.getNumberInstance()));
        units.add(new NumberTickUnit(10.0D, NumberFormat.getNumberInstance()));
        units.add(new NumberTickUnit(1.0D, NumberFormat.getNumberInstance()));
        units.add(new NumberTickUnit(0.5D, NumberFormat.getNumberInstance()));
        rangeAxis.setStandardTickUnits(units);

        // 柱子颜色
        GradientPaint gp0 = new GradientPaint(0.0F, 0.0F, new Color(124, 181, 236), 0.0F, 0.0F, new Color(124, 181, 236));
        // 组内第一组柱子颜色
        renderer.setSeriesPaint(0, gp0);
        // 设置图表背景图颜色
        if (null != config.getBackgroundColor()) {
            lineChart.getPlot().setBackgroundPaint(config.getBackgroundColor());
        }
        // 设置图表边框的颜色
        if (null != config.getOutlineColor()) {
            lineChart.getPlot().setOutlinePaint(config.getOutlineColor());
        }
        // 设置图表背景图
        if (null != config.getBackgroundImage()) {
            lineChart.getPlot().setBackgroundImage(config.getBackgroundImage());
        }
        if (null != consumer) {
            consumer.accept(lineChart);
        }
        return lineChart.createBufferedImage(config.getWidth(), config.getHeight(), BufferedImage.TYPE_INT_RGB, null);
    }

    /**
     * 绘制饼图，并生成图片
     *
     * @param config     图表配置参数
     * @param dataset    图表内容数据
     * @return 图片
     */
    public static BufferedImage drawPieChart(JFreeChartConfig config, DefaultPieDataset dataset) {
        JFreeChart pieChar = ChartFactory.createPieChart(config.getTitle(), dataset, true, true,
                false);
        PiePlot pieplot = (PiePlot) pieChar.getPlot();
//        DecimalFormat df = new DecimalFormat("0.00%");//获得一个DecimalFormat对象，主要是设置小数问题
//
//        NumberFormat nf = NumberFormat.getNumberInstance();//获得一个NumberFormat对象
//
//        StandardPieSectionLabelGenerator sp1 = new StandardPieSectionLabelGenerator("{0} {2}", nf, df);//获得StandardPieSectionLabelGenerator对象
//
//        pieplot.setLabelGenerator(sp1);//设置饼图显示百分比

        pieplot.setNoDataMessage("无数据显示");

        pieplot.setCircular(true);

//        pieplot.setLabelGap(0.02D);

        pieplot.setIgnoreNullValues(true);//设置不显示空值

        pieplot.setIgnoreZeroValues(true);//设置不显示负值

        pieplot.setExplodePercent("Category 1", 0.30);//其中的数字是控制出来多少的

        pieplot.setLabelFont(new Font("宋体",Font.BOLD,10));//解决乱码

        pieChar.getLegend().setItemFont(new Font("黑体",Font.BOLD,10));

        // 饼图颜色
        pieplot.setSectionPaint("男", new Color(145,204,117));
        pieplot.setSectionPaint("女", new Color(81, 114, 202));

        pieplot.setShadowPaint(Color.WHITE); // 设置绘图面板阴影的填充颜色

        // 设置图表背景图颜色
        if (null != config.getBackgroundColor()) {
            pieChar.getPlot().setBackgroundPaint(config.getBackgroundColor());
        }
        // 设置图表边框的颜色
        if (null != config.getOutlineColor()) {
            pieChar.getPlot().setOutlinePaint(config.getOutlineColor());
        }
        // 设置图表背景图
        if (null != config.getBackgroundImage()) {
            pieChar.getPlot().setBackgroundImage(config.getBackgroundImage());
        }
        return pieChar.createBufferedImage(config.getWidth(), config.getHeight(), BufferedImage.TYPE_INT_RGB, null);
    }

    /**
     * 绘制雷达图，并生成图片
     *
     * @param config     图表配置参数
     * @param dataset    图表内容数据
     * @return 图片流
     */
    public static BufferedImage drawSpiderChart(JFreeChartConfig config, DefaultCategoryDataset dataset) {
        MySpiderWebPlot spiderwebPlot= new MySpiderWebPlot(dataset);
        // 刻度
        spiderwebPlot.setTicks(6);
        // 设置起始角度
        spiderwebPlot.setStartAngle(90D);
        // 设置颜色
        spiderwebPlot.setSeriesPaint(0,new Color(124, 181, 236));
        spiderwebPlot.setSeriesPaint(1,Color.RED);
        // 设置折线粗细
        spiderwebPlot.setSeriesOutlineStroke(new BasicStroke(2));
        // 设置节点颜色
        spiderwebPlot.setSeriesOutlinePaint(0,new Color(124, 181, 236));
        spiderwebPlot.setSeriesOutlinePaint(1,Color.RED);
        JFreeChart spiderChart = new JFreeChart(config.getTitle(), TextTitle.DEFAULT_FONT, spiderwebPlot, false);
        LegendTitle legendtitle = new LegendTitle(spiderwebPlot);
        legendtitle.setPosition(RectangleEdge.BOTTOM);
        spiderChart.addSubtitle(legendtitle);
        // 主题
        ChartUtils.applyCurrentTheme(spiderChart);
        // 设置图表背景图颜色
        if (null != config.getBackgroundColor()) {
            spiderChart.getPlot().setBackgroundPaint(config.getBackgroundColor());
        }
        // 设置图表边框的颜色
        if (null != config.getOutlineColor()) {
            spiderChart.getPlot().setOutlinePaint(config.getOutlineColor());
        }
        // 设置图表背景图
        if (null != config.getBackgroundImage()) {
            spiderChart.getPlot().setBackgroundImage(config.getBackgroundImage());
        }
        return spiderChart.createBufferedImage(config.getWidth(), config.getHeight(), BufferedImage.TYPE_INT_RGB, null);
    }

    /**
     * 绘制卡特尔折线图
     *
     * @param config     图表配置参数
     * @param dataset    图表内容数据
     * @return 图片流
     */
    public static BufferedImage cartelChart(JFreeChartConfig config, CategoryDataset dataset) {
        JFreeChart chart = ChartFactory.createLineChart(config.getTitle(), (String)null, "分数（分）",generaLeft(dataset), PlotOrientation.HORIZONTAL, false, false, false);
        // 获取图表对象
        CategoryPlot plot = (CategoryPlot)chart.getPlot();
        // 获取分类轴
        CategoryAxis categoryAxis = plot.getDomainAxis();
        // 隐藏刻度
        categoryAxis.setTickMarksVisible(false);
        // 隐藏轴线
        categoryAxis.setAxisLineVisible(false);
        // 设置分类轴上部和底部编辑
        categoryAxis.setLowerMargin(0.01);
        categoryAxis.setUpperMargin(0);
        // 设置范围轴位置
        plot.setRangeAxisLocation(0, AxisLocation.BOTTOM_OR_RIGHT);

        // 获取分类轴字体
        Font tickLabelFont = categoryAxis.getTickLabelFont();
        // 添加左边轴数据
        CategoryAxis left = new CategoryAxis("");
        // 添加数据映射
        plot.setDataset(1, dataset);
        // 分类轴标签字体
        left.setTickLabelFont(tickLabelFont);
        // 设置分类轴顶端外边距
        left.setLowerMargin(0.01);
        // 设置分类轴底部外边距
        left.setUpperMargin(0);
        // 图片区域添加轴
        plot.setDomainAxis(1, left);
        // 设置轴位置
        plot.setDomainAxisLocation(1, AxisLocation.BOTTOM_OR_LEFT);
        // 设置轴对应dateset
        plot.mapDatasetToDomainAxis(1,1);

        CategoryAxis right = new CategoryAxis("");
        // 添加数据映射
        plot.setDataset(2, generaRight(dataset));
        // 分类轴标签字体
        right.setTickLabelFont(tickLabelFont);
        // 隐藏刻度
        right.setTickMarksVisible(false);
        // 隐藏轴线
        right.setAxisLineVisible(false);
        // 设置分类轴顶端外边距
        right.setLowerMargin(0.01);
        // 设置分类轴底部外边距
        right.setUpperMargin(0);
        // 图片区域添加轴
        plot.setDomainAxis(2, right);
        // 设置轴位置
        plot.setDomainAxisLocation(2, AxisLocation.BOTTOM_OR_RIGHT);
        // 设置轴对应dateset
        plot.mapDatasetToDomainAxis(2,2);

//        // 设置数据区域外边框
        plot.setOutlinePaint(new Color(230, 230, 230));

        //数据轴网格是否可见
        plot.setRangeGridlinesVisible(true);
        plot.setDomainGridlinesVisible(true);
        plot.setDomainGridlinePosition(CategoryAnchor.END);
//        //设置数据轴网格线宽度，不设置为虚线
        plot.setRangeGridlineStroke(new BasicStroke(1F));
        plot.setDomainGridlineStroke(new BasicStroke(1F));

        // 数据轴X
        NumberAxis rangeAxis = (NumberAxis)plot.getRangeAxis();
        // 数据轴刻度单位
        rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
        // 获取数据范围
        Range range = DatasetUtils.findRangeBounds(dataset);
        // 设置数据轴最大最小值
        rangeAxis.setUpperBound((range.getUpperBound() % 1 == 0 ? range.getUpperBound() + 1 : (int)range.getUpperBound())+ 2);
        rangeAxis.setLowerBound(((int)range.getLowerBound()) - 1);

        LineAndShapeRenderer renderer = (LineAndShapeRenderer)plot.getRenderer();
        // 显示折线数值
        renderer.setDefaultItemLabelsVisible(true);
        ItemLabelPosition position1 = new ItemLabelPosition(ItemLabelAnchor.OUTSIDE1, TextAnchor.CENTER_LEFT);
        renderer.setDefaultPositiveItemLabelPosition(position1);
        renderer.setDefaultNegativeItemLabelPosition(position1);
        renderer.setDefaultItemLabelGenerator(new StandardCategoryItemLabelGenerator());
        // 设置显示连接节点
        renderer.setDefaultShapesVisible(true);
        // 设置节点使用填充的颜色
        renderer.setUseFillPaint(true);
        // 设置节点填充颜色
        renderer.setDefaultFillPaint(new Color(124, 181, 236));
        // 设置折线粗细
        renderer.setSeriesStroke(0, new BasicStroke(2.0F));
        // 设置节点大小
        renderer.setSeriesOutlineStroke(0, new BasicStroke(2.0F));
        // 设置节点大小
        renderer.setSeriesShape(0, new Ellipse2D.Double(-2.5D, -2.5D, 5.0D, 5.0D));
        // 折线颜色
        GradientPaint gp0 = new GradientPaint(0.0F, 0.0F, new Color(124, 181, 236), 0.0F, 0.0F, new Color(124, 181, 236));
        // 组内第一组柱子颜色
        renderer.setSeriesPaint(0, gp0);
        // 设置并添加基线
        ValueMarker marker = new ValueMarker(5.5, Color.RED, new BasicStroke(1.0F));
        plot.addRangeMarker(marker, Layer.BACKGROUND);

        return chart.createBufferedImage(config.getWidth(), config.getHeight(), BufferedImage.TYPE_INT_RGB, null);
    }

    /**
     * 绘制MBTI人格特质量表
     *
     * @param config    图表配置参数
     * @param dataset   图表内容数据
     * @param rightDataset  图表内容数据
     * @return 图片流
     */
    public static BufferedImage createMBTIChart(JFreeChartConfig config, CategoryDataset dataset,CategoryDataset rightDataset) {
        JFreeChart chart = ChartFactory.createStackedBarChart(config.getTitle(), config.getCategoryAxisLabel(), config.getValueAxisLabel(), dataset, PlotOrientation.HORIZONTAL, false, true, false);
        CategoryPlot plot = (CategoryPlot) chart.getPlot();
        plot.setRangeAxisLocation(AxisLocation.BOTTOM_OR_RIGHT);
        plot.setRangeGridlinesVisible(true);
        plot.setRangeGridlineStroke(new BasicStroke(1.2F));
        plot.setOutlineVisible(false);
        plot.setAxisOffset(new RectangleInsets(UnitType.ABSOLUTE, 0.0D, -1.2D, 0.0D, 0.0D));

        // 底部分类项展示
        LegendTitle legend = new LegendTitle(plot.getRenderer(0));
        legend.setItemFont(new Font("宋体", Font.BOLD, 15));
        legend.setPosition(RectangleEdge.BOTTOM);
        chart.addSubtitle(legend);

        CategoryAxis domainAxis = plot.getDomainAxis();
        domainAxis.setTickMarkOutsideLength(6.0F);
        domainAxis.setTickMarkPaint(new Color(102,140,194));
        domainAxis.setAxisLineVisible(true);
        domainAxis.setAxisLinePaint(new Color(102,140,194));
        domainAxis.setAxisLineStroke(new BasicStroke(1.5F));

        NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
        rangeAxis.setLowerBound(-100);
        rangeAxis.setUpperBound(100);
        // 隐藏轴线、刻度线
        rangeAxis.setAxisLineVisible(false);
        rangeAxis.setTickMarksVisible(false);

        // 柱状区域（平面，颜色，宽度）
        StackedBarRenderer renderer = (StackedBarRenderer) plot.getRenderer();
        renderer.setBarPainter(new StandardBarPainter());
        renderer.setSeriesPaint(0, new Color(247,163,92));
        renderer.setSeriesPaint(1, new Color(144,237,125));
        renderer.setSeriesPaint(2, new Color(67,67,72));
        renderer.setSeriesPaint(3, new Color(125,182,236));
        renderer.setMaximumBarWidth(0.12);

        // 右边y轴
        plot.setDataset(1, rightDataset);
        CategoryAxis xAxis2 = new CategoryAxis("");
        xAxis2.setTickMarkOutsideLength(6.0F);
        xAxis2.setTickMarkPaint(new Color(102,140,194));
        xAxis2.setAxisLineVisible(true);
        xAxis2.setAxisLinePaint(new Color(102,140,194));
        xAxis2.setAxisLineStroke(new BasicStroke(1.5F));
        xAxis2.setTickLabelFont(((StandardChartTheme)ChartFactory.getChartTheme()).getRegularFont());
        plot.setDomainAxis(1, xAxis2);
        plot.setDomainAxisLocation(1, AxisLocation.BOTTOM_OR_RIGHT);
        plot.mapDatasetToDomainAxis(1,1);

        // 设置负数轴刻度为正数
        DecimalFormat nf = new DecimalFormat("-");
        nf.setNegativePrefix("");
        nf.setPositivePrefix("");
        nf.setMaximumFractionDigits(1);
        rangeAxis.setNumberFormatOverride(nf);//y轴节点格式
        // 设置图表背景图颜色
        plot.setBackgroundPaint(SystemColor.WHITE);
        // 设置图表边框的颜色
        plot.setOutlinePaint(SystemColor.WHITE);
        return chart.createBufferedImage(config.getWidth(), config.getHeight(), BufferedImage.TYPE_INT_RGB, null);
    }

    /**
     * 绘制QIUS在校学生气质量表（QTS）
     *
     * @param config    图表配置参数
     * @param dataset   图表内容数据
     * @return 图片流
     */
    public static BufferedImage createQTSChart(JFreeChartConfig config, final XYDataset dataset) {
        JFreeChart chart = ChartFactory.createXYLineChart(config.getTitle(), "P维度", "B维度", dataset, PlotOrientation.VERTICAL, false, true, false);
        XYPlot plot = (XYPlot)chart.getPlot();

        drawQTSBasic(plot);

        ValueAxis rangeAxis = plot.getRangeAxis();
        rangeAxis.setUpperBound(60);
        rangeAxis.setLowerBound(-60);

        ValueAxis domainAxis = plot.getDomainAxis();
        domainAxis.setUpperBound(60);
        domainAxis.setLowerBound(-60);

        XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
        renderer.setDefaultItemLabelGenerator(new StandardXYItemLabelGenerator("分数({1},{2})"));
        renderer.setDefaultItemLabelsVisible(true);
        renderer.setDefaultItemLabelFont(new Font("Dialog", Font.BOLD, 14));
        renderer.setDefaultShape(new Ellipse2D.Double(-4.0D, -4.0D, 8.0D, 8.0D));
        renderer.setAutoPopulateSeriesShape(false);
        plot.setRenderer(renderer);
        return chart.createBufferedImage(config.getWidth(), config.getHeight(), BufferedImage.TYPE_INT_RGB, null);
    }

    /**
     * 明尼苏达多相个性测查表（MMPI)
     *
     * @param config    图表配置参数
     * @param dataset   图表内容数据
     * @return 图片流
     */
    public static BufferedImage createMMPIChart(JFreeChartConfig config, DefaultCategoryDataset dataset) {
        JFreeChart chart = ChartFactory.createLineChart(config.getTitle(), config.getCategoryAxisLabel(),
                config.getValueAxisLabel(), dataset, PlotOrientation.VERTICAL,
                false, true, false);

        CategoryPlot plot = (CategoryPlot)chart.getPlot();
        plot.setRangePannable(true);
        plot.setDomainGridlinesVisible(false);
        plot.setRangeGridlineStroke(new BasicStroke(BasicStroke.CAP_ROUND));

        ValueMarker marker = new ValueMarker(40, Color.RED, new BasicStroke(1.0F));
        ValueMarker marker1 = new ValueMarker(60, Color.RED, new BasicStroke(1.0F));
        plot.addRangeMarker(marker);
        plot.addRangeMarker(marker1);

        CategoryMarker categoryMarker = new CategoryMarker("疑病症【Hs】", Color.RED, new BasicStroke(1.0F));
        categoryMarker.setDrawAsLine(true);

        plot.addDomainMarker(categoryMarker);
        LineAndShapeRenderer renderer = (LineAndShapeRenderer)plot.getRenderer();
        renderer.setDefaultShapesVisible(true);
        renderer.setDefaultShapesFilled(true);
        renderer.setSeriesShape(0, ShapeUtils.createDiamond(4.0F));
        renderer.setSeriesPaint(0,new Color(69,114,167));
        renderer.setDefaultItemLabelsVisible(true);
        renderer.setDefaultItemLabelGenerator(new StandardCategoryItemLabelGenerator());
        renderer.setDefaultNegativeItemLabelPosition(new ItemLabelPosition());

        NumberAxis rangeAxis = (NumberAxis)plot.getRangeAxis();
        rangeAxis.setUpperMargin(0.1);
        rangeAxis.setAutoRangeIncludesZero(true);
        TickUnits units = new TickUnits();
        units.add(new NumberTickUnit(100.0D, NumberFormat.getNumberInstance()));
        units.add(new NumberTickUnit(50.0D, NumberFormat.getNumberInstance()));
        units.add(new NumberTickUnit(10.0D, NumberFormat.getNumberInstance()));
        units.add(new NumberTickUnit(1.0D, NumberFormat.getNumberInstance()));
        rangeAxis.setStandardTickUnits(units);
        rangeAxis.setTickMarksVisible(false);

        CategoryAxis domainAxis = plot.getDomainAxis();
        domainAxis.setTickMarkOutsideLength(5f);
        // 设置分类轴刻度标签最多行
        domainAxis.setMaximumCategoryLabelLines(2);
        domainAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45);
        return chart.createBufferedImage(config.getWidth(), config.getHeight(), BufferedImage.TYPE_INT_RGB, null);
    }


    /**
     * 绘制艾森克EPQ量表
     *
     * @param config     图表配置参数
     * @param dataset    图表内容数据
     * @return 图片流
     */
    public static BufferedImage createEPQChart(JFreeChartConfig config, XYDataset dataset) {

        JFreeChart xyLineChart = ChartFactory.createXYLineChart(config.getTitle(), "内外向性", "精神质", dataset, PlotOrientation.VERTICAL, false, false, false);

        XYPlot xyPlot = xyLineChart.getXYPlot();

        xyPlot.getRangeAxis().setRange(0D,100D);

        xyPlot.getDomainAxis().setRange(0D,100D);


        XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer();
        renderer.setDefaultItemLabelGenerator(new StandardXYItemLabelGenerator("分数({1},{2})"));
        renderer.setDefaultItemLabelsVisible(true);
        renderer.setDefaultShape(new Ellipse2D.Double(-4.0D, -4.0D, 8.0D, 8.0D));
        renderer.setAutoPopulateSeriesShape(false);

        xyPlot.setRenderer(renderer);

        drawEPQBasic(xyPlot);

        xyPlot.setDomainGridlinesVisible(false);
        xyPlot.setRangeGridlinesVisible(false);

        return xyLineChart.createBufferedImage(config.getWidth(), config.getHeight(), BufferedImage.TYPE_INT_RGB, null);
    }

    private static void drawEPQBasic(XYPlot plot) {

        ValueMarker nMarker = new ValueMarker(50.0D, Color.black, new BasicStroke(1.5F));
        nMarker.setLabel("E维度（内外倾向性）");
        nMarker.setLabelAnchor(RectangleAnchor.BOTTOM_RIGHT);
        nMarker.setLabelTextAnchor(TextAnchor.TOP_RIGHT);
        nMarker.setLabelOffsetType(LengthAdjustmentType.EXPAND);
        nMarker.setLabelBackgroundColor(Color.white);
        nMarker.setLabelFont(new Font("Dialog", Font.PLAIN, 10));
        plot.addRangeMarker(nMarker);

        ValueMarker eMarker = new ValueMarker(50.0D, Color.black, new BasicStroke(1.5F));
        eMarker.setLabel("N维度（情绪稳定性）");
        eMarker.setLabelAnchor(RectangleAnchor.BOTTOM_RIGHT);
        eMarker.setLabelTextAnchor(TextAnchor.BOTTOM_LEFT);
        eMarker.setLabelOffsetType(LengthAdjustmentType.EXPAND);
        eMarker.setLabelBackgroundColor(Color.white);
        eMarker.setLabelFont(new Font("Dialog", Font.PLAIN, 10));
        plot.addDomainMarker(eMarker);


        ValueMarker valueMarker1 = new ValueMarker(56.7D, Color.lightGray, new BasicStroke(1.5F));
        plot.addDomainMarker(valueMarker1);
        plot.addRangeMarker(valueMarker1);

        ValueMarker valueMarker2 = new ValueMarker(43.3D, Color.lightGray, new BasicStroke(1.5F));
        plot.addDomainMarker(valueMarker2);
        plot.addRangeMarker(valueMarker2);

        ValueMarker valueMarker3 = new ValueMarker(38.5D, Color.lightGray, new BasicStroke(1.5F , BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER, 15.0f, new float[] {3.0f,3.0f} ,0.0f));
        plot.addDomainMarker(valueMarker3);
        plot.addRangeMarker(valueMarker3);

        ValueMarker valueMarker4 = new ValueMarker(61.5D, Color.lightGray, new BasicStroke(1.5F , BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER, 15.0f, new float[] {3.0f,3.0f} ,0.0f));
        plot.addDomainMarker(valueMarker4);
        plot.addRangeMarker(valueMarker4);

        Font font = new Font("Dialog",Font.PLAIN, 13);

        XYTextAnnotation top_left_text = new XYTextAnnotation("外向、不稳定胆汁质", 75.0D, 75.0D);
        top_left_text.setFont(font);
        top_left_text.setTextAnchor(TextAnchor.BASELINE_CENTER);

        XYTextAnnotation top_right_text = new XYTextAnnotation("内向、不稳定抑郁质", 25.0D, 75.0D);
        top_right_text.setFont(font);
        top_right_text.setTextAnchor(TextAnchor.BASELINE_CENTER);

        XYTextAnnotation bottom_left_text = new XYTextAnnotation("内向、稳定粘液质", 25.0D, 25.0D);
        bottom_left_text.setFont(font);
        bottom_left_text.setTextAnchor(TextAnchor.BASELINE_CENTER);

        XYTextAnnotation bottom_right_text = new XYTextAnnotation("外向、稳定多血质", 75.0D, 25.0D);
        bottom_right_text.setFont(font);
        bottom_right_text.setTextAnchor(TextAnchor.BASELINE_CENTER);

        plot.addAnnotation(top_left_text);
        plot.addAnnotation(top_right_text);
        plot.addAnnotation(bottom_left_text);
        plot.addAnnotation(bottom_right_text);

    }

    private static void drawQTSBasic(final XYPlot plot) {

        plot.setDomainGridlinesVisible(false);
        plot.setRangeGridlinesVisible(false);

        XYLineAnnotation top_line = new XYLineAnnotation(-20.0D, 20.0D, 20.0D, 20.0D, new BasicStroke(1.5F, 1, 1, 1.0F, new float[] {1F, 10F}, 0.0F), Color.black);
        plot.addAnnotation(top_line);

        XYLineAnnotation right_line = new XYLineAnnotation(20.0D, 20.0D, 20.0D, -20.0D, new BasicStroke(1.5F, 1, 1, 1.0F, new float[] {1F, 10F}, 0.0F), Color.black);
        plot.addAnnotation(right_line);

        XYLineAnnotation bottom_line = new XYLineAnnotation(-20.0D, -20.0D, 20.0D, -20.0D, new BasicStroke(1.5F, 1, 1, 1.0F, new float[] {1F, 10F}, 0.0F), Color.black);
        plot.addAnnotation(bottom_line);

        XYLineAnnotation left_line = new XYLineAnnotation(-20.0D, 20.0D, -20.0D, -20.0D, new BasicStroke(1.5F, 1, 1, 1.0F, new float[] {1F, 10F}, 0.0F), Color.black);
        plot.addAnnotation(left_line);

        ValueMarker valueMarker = new ValueMarker(0, Color.black, new BasicStroke(1.0F));
        valueMarker.setLabel("B维度");
        valueMarker.setLabelAnchor(RectangleAnchor.BOTTOM_RIGHT);
        valueMarker.setLabelTextAnchor(TextAnchor.TOP_RIGHT);
        valueMarker.setLabelOffsetType(LengthAdjustmentType.EXPAND);
        valueMarker.setLabelBackgroundColor(Color.white);
        valueMarker.setLabelFont(new Font("宋体", Font.PLAIN, 10));
        plot.addRangeMarker(valueMarker);

        ValueMarker valueMarker1 = new ValueMarker(0, Color.black, new BasicStroke(1.0F));
        valueMarker1.setLabel("P维度");
        valueMarker1.setLabelAnchor(RectangleAnchor.BOTTOM_RIGHT);
        valueMarker1.setLabelTextAnchor(TextAnchor.BOTTOM_LEFT);
        valueMarker1.setLabelOffsetType(LengthAdjustmentType.EXPAND);
        valueMarker1.setLabelBackgroundColor(Color.white);
        valueMarker1.setLabelFont(new Font("宋体", Font.PLAIN, 10));
        plot.addDomainMarker(valueMarker1);

        Font font = new Font("宋体",Font.PLAIN, 13);

        XYBoxAnnotation top_left1 = new XYBoxAnnotation(-65.0D, 20.0D, -20.0D, 65.0D, new BasicStroke(2.0F), Color.black);
        XYBoxAnnotation top_left2 = new XYBoxAnnotation(-65.0D, 42.5D, -42.5D, 65.0D,new BasicStroke(2.0F), Color.black);

        XYBoxAnnotation top_right1 = new XYBoxAnnotation(20.0D, 20.0D, 65.0D, 65.0D, new BasicStroke(2.0F), Color.black);
        XYBoxAnnotation top_right2 = new XYBoxAnnotation(42.5D, 42.5D, 65.0D, 65.0D,new BasicStroke(2.0F), Color.black);

        XYBoxAnnotation bottom_left1 = new XYBoxAnnotation(-65.0D, -65.0D, -20.0D, -20.0D, new BasicStroke(2.0F), Color.black);
        XYBoxAnnotation bottom_left2 = new XYBoxAnnotation(-65.0D, -65.0D, -42.5D, -42.5D,new BasicStroke(2.0F), Color.black);

        XYBoxAnnotation bottom_right1 = new XYBoxAnnotation(42.5D, -65.0D, 65.0D, -42.5D,  new BasicStroke(2.0F), Color.black);
        XYBoxAnnotation bottom_right2 = new XYBoxAnnotation(20.0D, -65.0D, 65.0D, -20.0D,new BasicStroke(2.0F), Color.black);

        XYTextAnnotation center_text = new XYTextAnnotation("多项气质混合型", 0.0D, 0.0D);
        center_text.setFont(font);
        center_text.setTextAnchor(TextAnchor.BOTTOM_CENTER);

        XYTextAnnotation top_left_text1 = new XYTextAnnotation("典型胆汁质", -45.0D, 47.5D);
        top_left_text1.setFont(font);
        top_left_text1.setTextAnchor(TextAnchor.HALF_ASCENT_RIGHT);
        XYTextAnnotation top_left_text2 = new XYTextAnnotation("一般胆汁质", -25.0D, 25.0D);
        top_left_text2.setFont(font);
        top_left_text2.setTextAnchor(TextAnchor.HALF_ASCENT_RIGHT);
        XYTextAnnotation top_left_text3 = new XYTextAnnotation("胆汁-多血质", -10.0D, 50.0D);
        top_left_text3.setFont(font);
        top_left_text3.setTextAnchor(TextAnchor.CENTER);
        XYTextAnnotation top_left_text4 = new XYTextAnnotation("胆汁-抑郁质", -32.5D, 10.0D);
        top_left_text4.setFont(font);
        top_left_text4.setTextAnchor(TextAnchor.HALF_ASCENT_RIGHT);

        XYTextAnnotation top_right_text1 = new XYTextAnnotation("典型多血质", 45.0D, 47.5D);
        top_right_text1.setFont(font);
        top_right_text1.setTextAnchor(TextAnchor.HALF_ASCENT_LEFT);
        XYTextAnnotation top_right_text2 = new XYTextAnnotation("一般多血质", 25.0D, 25.0D);
        top_right_text2.setFont(font);
        top_right_text2.setTextAnchor(TextAnchor.HALF_ASCENT_LEFT);
        XYTextAnnotation top_right_text3 = new XYTextAnnotation("多血-胆汁质", 10.0D, 50.0D);
        top_right_text3.setFont(font);
        top_right_text3.setTextAnchor(TextAnchor.CENTER);
        XYTextAnnotation top_right_text4 = new XYTextAnnotation("多血-粘液质", 32.5D, 10.0D);
        top_right_text4.setFont(font);
        top_right_text4.setTextAnchor(TextAnchor.HALF_ASCENT_LEFT);

        XYTextAnnotation bottom_left_text1 = new XYTextAnnotation("典型抑郁质", -45.0D, -47.5D);
        bottom_left_text1.setFont(font);
        bottom_left_text1.setTextAnchor(TextAnchor.HALF_ASCENT_RIGHT);
        XYTextAnnotation bottom_left_text2 = new XYTextAnnotation("一般抑郁质", -25.0D, -25.0D);
        bottom_left_text2.setFont(font);
        bottom_left_text2.setTextAnchor(TextAnchor.HALF_ASCENT_RIGHT);
        XYTextAnnotation bottom_left_text3 = new XYTextAnnotation("抑郁-粘液质", -10.0D, -50.0D);
        bottom_left_text3.setFont(font);
        bottom_left_text3.setTextAnchor(TextAnchor.CENTER);
        XYTextAnnotation bottom_left_text4 = new XYTextAnnotation("抑郁-胆汁质", -32.5D, -10.0D);
        bottom_left_text4.setFont(font);
        bottom_left_text4.setTextAnchor(TextAnchor.HALF_ASCENT_RIGHT);

        XYTextAnnotation bottom_right_text1 = new XYTextAnnotation("典型粘液质", 45.0D, -47.5D);
        bottom_right_text1.setFont(font);
        bottom_right_text1.setTextAnchor(TextAnchor.HALF_ASCENT_LEFT);
        XYTextAnnotation bottom_right_text2 = new XYTextAnnotation("一般粘液质", 25.0D, -25.0D);
        bottom_right_text2.setFont(font);
        bottom_right_text2.setTextAnchor(TextAnchor.HALF_ASCENT_LEFT);
        XYTextAnnotation bottom_right_text3 = new XYTextAnnotation("粘液-抑郁质", 10.0D, -50.0D);
        bottom_right_text3.setFont(font);
        bottom_right_text3.setTextAnchor(TextAnchor.CENTER);
        XYTextAnnotation bottom_right_text4 = new XYTextAnnotation("粘液-多血质", 32.5D, -10.0D);
        bottom_right_text4.setFont(font);
        bottom_right_text4.setTextAnchor(TextAnchor.HALF_ASCENT_LEFT);

        //将上面的边界线条，说明文字加入到xyplot中。
        plot.addAnnotation(top_left1);
        plot.addAnnotation(top_left2);
        plot.addAnnotation(top_right1);
        plot.addAnnotation(top_right2);
        plot.addAnnotation(bottom_left1);
        plot.addAnnotation(bottom_left2);
        plot.addAnnotation(bottom_right1);
        plot.addAnnotation(bottom_right2);
        plot.addAnnotation(top_left_text1);
        plot.addAnnotation(center_text);
        plot.addAnnotation(top_left_text2);
        plot.addAnnotation(top_left_text3);
        plot.addAnnotation(top_left_text4);
        plot.addAnnotation(top_right_text1);
        plot.addAnnotation(top_right_text2);
        plot.addAnnotation(top_right_text3);
        plot.addAnnotation(top_right_text4);
        plot.addAnnotation(bottom_left_text1);
        plot.addAnnotation(bottom_left_text2);
        plot.addAnnotation(bottom_left_text3);
        plot.addAnnotation(bottom_left_text4);
        plot.addAnnotation(bottom_right_text1);
        plot.addAnnotation(bottom_right_text2);
        plot.addAnnotation(bottom_right_text3);
        plot.addAnnotation(bottom_right_text4);
    }

    private static CategoryDataset generaLeft(CategoryDataset dataset) {
        DefaultCategoryDataset newDataset = new DefaultCategoryDataset();
        Map<Object, String> map = new LinkedHashMap<>();
        map.put("乐群性", "沉默孤独");
        map.put("聪慧性", "学识浅薄");
        map.put("稳定性", "情绪激动");
        map.put("恃强性", "谦逊顺从");
        map.put("兴奋性", "严肃谨慎");
        map.put("有恒性", "权宜敷衍");
        map.put("敢为性", "畏怯退缩");
        map.put("敏感性", "理智、注重实际");
        map.put("怀疑性", "信赖随和");
        map.put("幻想性", "现实、合乎常规");
        map.put("世故性", "坦白直率、天真");
        map.put("忧虑性", "安详沉着、有自信心");
        map.put("实验性", "保守、附庸传统");
        map.put("独立性", "依赖、随群附众");
        map.put("自律性", "矛盾冲突、不明大体");
        map.put("紧张性", "心平气和");
        for (int i = 0; i < dataset.getColumnKeys().size(); i++) {
            if (map.containsKey(dataset.getColumnKey(i))) {
                newDataset.addValue(dataset.getValue(0, i), dataset.getRowKey(0), map.get(dataset.getColumnKey(i)));
            }
        }
        return newDataset;
    }

    private static CategoryDataset generaRight(CategoryDataset dataset) {
        DefaultCategoryDataset newDataset = new DefaultCategoryDataset();
        Map<Object, String> map = new LinkedHashMap<>();
        map.put("乐群性", "乐群外向");
        map.put("聪慧性", "聪慧、富有才识");
        map.put("稳定性", "情绪稳定");
        map.put("恃强性", "好强固执");
        map.put("兴奋性", "轻松兴奋");
        map.put("有恒性", "有恒负责");
        map.put("敢为性", "冒险敢为");
        map.put("敏感性", "敏感、感情用事");
        map.put("怀疑性", "怀疑刚愎");
        map.put("幻想性", "幻想、狂荡不羁");
        map.put("世故性", "精明能干、世故");
        map.put("忧虑性", "忧虑抑郁、烦恼多端");
        map.put("实验性", "自由、批评激进");
        map.put("独立性", "自主、当机立断");
        map.put("自律性", "知己知彼、自律严谨");
        map.put("紧张性", "紧张困扰");
        for (int i = 0; i < dataset.getColumnKeys().size(); i++) {
            if (map.containsKey(dataset.getColumnKey(i))) {
                newDataset.addValue(dataset.getValue(0, i), dataset.getRowKey(0), map.get(dataset.getColumnKey(i)));
            }
        }
        return newDataset;
    }

}

